/*
**  File: MultiPlot_mac.c
*/

#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <console.h>


#define    kFontName    "\pCourier"
#define    kFontSize    9
#define    kFontWidth   6      /* for calculation of label size 
                                  (should be the same as in MultiPlot.c) */

#define    tic        3        /* pixels for tic marks */
#define    dtic       1        /* pixels for data tic marks */
#define    xlabshft   2        /* pixelshift for aligning x label to tics */
#define    ylabshft   3        /* pixelshift for aligning y label to tics */


#ifdef CONSOLE
    #define    kNcols     63        /* gives maximum window with Courier 9 */
    #define    kNrows     27        /* calc'n in console.c incorrect ??? */
#else
    #ifdef THUIS
        #define    kWind        128
    #endif
    #ifdef LAB
        #define    kWind        129
    #endif
    #define    kMovToFront    (WindowPtr)-1L
#endif

#ifndef CONSOLE
    #include "Event_mac.h"
#endif

#include "Functs.h"
#include "MultiPlotTypes.h"
#include "MultiPlot_mac.h"

/*************/
/*  Globals  */
/*************/

GrafPtr    oldPort;

Boolean    datatic = true;

#ifndef CONSOLE
extern char  savChar;       /* import from Event_mac.c */
extern short savH, savV;    /* import from Event_mac.c */
#endif

/* the next variables are imported from MultiPlot.c */

extern FILE       *fpg;           /* the console file associated with the graphics window */
                                  /* used ifdef CONSOLE; otherwise use graphics 
                                     window not associated with console */
extern WindowPtr  window;         /* the graphics window */
extern char       xfmt[20];       /* format string for labels on x-axis */
extern char       yfmt[20];       /* format string for labels on y-axis */
extern int        xlab;           /* pixels in y direction for x-axis labels */
extern int        ylab;           /* pixels in x direction for y-axis labels */
extern int        ntic;           /* number of tic mark intervals */
extern Boolean    graph_on;

static PlotRec    *plotrecs = NULL;


/**************** PlotData ****************/

#define    ROUND        0.5
#define    size_STRING  80

void  PlotData( MyDatarecPtr xdata, MyDatarecPtr ydata, int data_count, 
                MyDatasize *DDsize,
                int xminscreen, int xmaxscreen, int yminscreen, int ymaxscreen )
{
    MyDataPtr  xd, yd;
    MyData     xmax, ymax, xmin, ymin;  /* PlotPrep makes sure they */
    MyData     xdel, ydel;              /* have integer value */

    double     xdelscreen, ydelscreen, xmap, ymap;
                                        /* rounded to int by adding ROUND */
    PlotRec    *plotrec, *newrec;
    int        i, j, xcoord, ycoord;
    char       string[size_STRING];

/*  char    str[size_STRING];  static int   yy=200;    */

    xmin = DDsize->xmin;
    xmax = DDsize->xmax;
    ymin = DDsize->ymin;
    ymax = DDsize->ymax;
    xdel = (xmax-xmin) / ntic;
    ydel = (ymax-ymin) / ntic;
    xdelscreen = (double)(xmaxscreen-xminscreen) / ntic;
    ydelscreen = (double)(ymaxscreen-yminscreen) / ntic;
    xmap = (double)(xmaxscreen-xminscreen) / (xmax-xmin);
    ymap = (double)(ymaxscreen-yminscreen) / (ymax-ymin);
    
    newrec = NEW( PlotRec, 1 );
    if ( !newrec )
    	NoMemErr( "PlotData: newrec" );
    if ( !plotrecs )
    	plotrecs = newrec;
    else
    	plotrec->next = newrec;
    plotrec = newrec;
    plotrec->xminscreen = xminscreen;
    plotrec->xmaxscreen = xmaxscreen;
    plotrec->yminscreen = yminscreen;
    plotrec->ymaxscreen = ymaxscreen;
    plotrec->xmin = xmin;
    plotrec->xmax = xmax;
    plotrec->xmap = xmap;
    plotrec->ymap = ymap;

/*
    sprintf(str,"xmin, xmax, ymin, ymax: %g %g %g %g\n",xmin,xmax,ymin,ymax);
    MoveTo(5,yy);DrawString(CtoPstr(str));yy+=12;
    sprintf(str,"xdelscreen, ydelscreen: %lg %lg\n",xdelscreen,ydelscreen);
    MoveTo(5,yy);DrawString(CtoPstr(str));yy+=12;
    sprintf(str,"xmaxscreen, ymaxscreen: %i %i\n",xmaxscreen,ymaxscreen);
    MoveTo(5,yy);DrawString(CtoPstr(str));yy+=12;
    sprintf(str,"xminscreen, yminscreen: %i %i\n",xminscreen,yminscreen);
*/

/* plot data */

	ForeColor( greenColor );
    xd = xdata->data;
    yd = ydata->data;
    xcoord = xminscreen + (int)((*xd-xmin)*xmap + ROUND );
    ycoord = ymaxscreen - (int)((*yd-ymin)*ymap + ROUND );
    MoveTo( xcoord, ycoord );
    xd++;
    yd++;
    for ( i=1; i<data_count; i++ )
    {
        xcoord = xminscreen + (int)((*xd-xmin)*xmap + ROUND );
        ycoord = ymaxscreen - (int)((*yd-ymin)*ymap + ROUND );
        LineTo( xcoord, ycoord );
        if ( datatic )
        {
            MoveTo( xcoord, ymaxscreen );
            LineTo( xcoord, ymaxscreen-dtic );
            MoveTo( xminscreen, ycoord );
            LineTo( xminscreen+dtic, ycoord );
            MoveTo( xcoord, ycoord );
        }

        xd++;
        yd++;
    }
	ForeColor( blackColor );

/* draw axes */

    MoveTo( xminscreen, yminscreen );
    LineTo( xminscreen, ymaxscreen );
    LineTo( xmaxscreen, ymaxscreen );

/* tic marks and labels on y-axis */

    for ( i=0; i<=ntic; i++ )
    {
        j = (int)(ymaxscreen - i*ydelscreen + ROUND );
        MoveTo( xminscreen, j );
        LineTo( xminscreen+tic, j );
        if ( i==0 || i == ntic )
            continue;
        MoveTo( xminscreen-ylab, j+ylabshft);
        sprintf( string, yfmt, ymin + i*ydel );
        DrawString( CtoPstr( string ) );
    }

/* tic marks and labels on x-axis */

    for ( i=0; i<=ntic; i++ )
    {
        j = (int)(xminscreen + i*xdelscreen + ROUND );
        MoveTo( j, ymaxscreen-tic );
        LineTo( j, ymaxscreen );
        if ( i == ntic )
            break;
        sprintf( string, xfmt, xmin + i*xdel );
        MoveTo( j - ( LenStr(string) * kFontWidth ) / 2, 
                ymaxscreen+xlab );
        DrawString( CtoPstr( string ) );
    }

}

#undef    ROUND
#undef    size_STRING

/**************** FindPoint ****************/

...loop through plotrecs
...find savH,V in one of the minscreen..maxscreen regions
...transform to data coords -> new xmin/max and/or ymin/max (can be stored in new DDsize)
...redo, by returning 'z' from GetKey2 -> in MultiPlot KEEP iyp and jump to next

/**************** GraphPageInit ****************/

void    GraphPageInit( char *text )
{
    short     theFont;
    Str255    title;
    RGBColor      background = { 0xFFFF, 0xFFFF, 0xF000 };
	PixPatHandle  pp;

    strcpy( (char *)title, text );
    CtoPstr( title );
    
    GetPort( &oldPort );
    
#ifdef CONSOLE

/* set up graphics window associated with console-file fpg */
/* stdout reopened on this console (print output seems impossible otherwise) */
/* reading can be done from fpg */

    GetFNum( kFontName, &theFont );
    console_options.txFont = theFont;
    console_options.txSize = kFontSize;
    console_options.title = title;
    console_options.ncols = kNcols;
    console_options.nrows = kNrows;
    console_options.top = 38;
    console_options.left = 0;
    fpg = fopenc();
    if ( !fpg )
    {
        puts( "can't open fpg console" );
        exit( 1 );
    }
    if ( !freopenc( fpg, stdout ) )
    {
        puts( "can't reopen stdout console" );
        exit( 1 );
    }
    printf( " " );        /* screen is erased at first write */
    cshow( stdout );
    window = fpg->window;
    SetPort( window );

#else

/* set up independent graphics window */

    if ( !window )
    {
        window = GetNewCWindow( kWind, nil, kMovToFront );    
        if ( !window )
        {
            puts( "Couldn't load WIND resource" );
            exit( 1 );
        }
    }
    SetPort( window );
    EraseRect( &window->portRect );
    SetWTitle( window, title); 
    GetFNum( kFontName, &theFont );
    TextFont( theFont );
    TextSize( kFontSize );
    ShowWindow( window );
    SelectWindow( window );
    
/*
	RGBForeColor( &background );
	PaintRect( &(window->portRect) );
	ForeColor( blackColor );
*/

	pp = NewPixPat();
	MakeRGBPat( pp, &background );
	FillCRect( &(window->portRect), pp );

/*
	pp = GetPixPat( 128 );
	if ( !pp )
		puts( "could not load the pattern resource" );
	else
		FillCRect( &(window->portRect), pp );
*/

#endif

    graph_on = true;
}

/**************** GraphPageEnd ****************/

void GraphPageEnd( void )
{
    if ( !graph_on )
        return;

#ifdef CONSOLE

/* reopen stdout on the original console */

    fclose( fpg );
    freopenc( stdin, stdout);

#else
    
    HideWindow( window );
    cshow( stdout );

#endif

    SetPort( oldPort );
    graph_on = false;
}

#ifndef CONSOLE

/**************** GetKey1 ****************/

Boolean    GetKey1( int *c )
{
    EventRecord        event;
    short            eventMask = keyDownMask;
    Boolean        done = FALSE;
    
    while ( !done )
        if ( WaitNextEvent( eventMask, &event, LONG_MAX, nil ) )
        {
            if ( event.what == keyDown )
            {
                *c = (int)(event.message & charCodeMask);
                return( TRUE );
            }
            done = TRUE;
        } 
    /* do nothing */ ;
        
    return ( FALSE );
}

/**************** GetKey2 ****************/

Boolean    GetKey2( int *c )
{
    ActionTyp  action;
    enum { nozoom, zoomx, zoomy, zoomboth }....

    action = GetAction();

    switch ( action )
    {
        case eKey:
        	if ( savChar == 'z' )
        	{
        		if ( GetAction() == eKey )
        		{
        			switch( savChar )
        			{
        				case 'x':
        					zoom = zoomx;
        					break;
        				case 'y':
        					zoom = zoomy;
        					break;
        				case 'b':
        					zoom = zoomboth;
        					break;
        				default:
        					zoom = nozoom;
        			}
        		}
        	}
            *c = savChar;
            return( TRUE );
        case ePos:
        	if ( zoom != nozoom )
        	{
        		FindPoint...
        		...
        		*c = 'z';
        		return( TRUE );
        	}
        case eQuit:
            ExitToShell();
        default:
            return( FALSE );
    }
}

#endif
